/*	Reference implementation of hash family LUX
	Author: Ivica Nikolic, University of Luxembourg
*/

#include <stdio.h>
#include <string.h>
#include "LUX.h"

/* Table look-up */
#define TL(table,input,shift) table[(input >> shift) & 0xff]

/* Update core element for LUX-224 and LUX-256 */
#define UPVAR32(nv,z1,ov,z2,in,l0,l1,l2,l3,add)									\
	nv##in##z1=  TL(Te0,ov##l0##z2,24) ^ TL(Te1,ov##l1##z2,16) ^ TL(Te2,ov##l2##z2,8)  ^ TL(Te3,ov##l3##z2,0)##add;

/* Update core element for LUX-384 and LUX-512 */
#define UPVAR64(nv,z1,ov,z2,in,l0,l1,l2,l3,l4,l5,l6,l7,add)									\
	nv##in##z1= TL(T640,ov##l0##z2,56) ^ TL(T641,ov##l1##z2,48) ^ TL(T642,ov##l2##z2,40) ^ TL(T643,ov##l3##z2,32) ^ \
				TL(T644,ov##l4##z2,24) ^ TL(T645,ov##l5##z2,16) ^ TL(T646,ov##l6##z2, 8) ^ TL(T647,ov##l7##z2,0)##add;

/* One round for optimized LUX-224 and LUX-256.  */
#define ONEROUND(offSet,t,z1,s,z2,bf, p,data)					\
	do {														\
		s##0##z2^=*(u32 *)(data+offSet);						\
		bf[(p+13)%16]^=*(u32 *)(data+offSet);					\
		UPVAR32(t,z1,s,z2,0,0,1,3,4,^0x2ad01c64)				\
		UPVAR32(t,z1,s,z2,1,1,2,4,5,)							\
		UPVAR32(t,z1,s,z2,2,2,3,5,6,)							\
		UPVAR32(t,z1,s,z2,3,3,4,6,7,)							\
		UPVAR32(t,z1,s,z2,4,4,5,7,0,)							\
		UPVAR32(t,z1,s,z2,5,5,6,0,1,)							\
		UPVAR32(t,z1,s,z2,6,6,7,1,2,)							\
		UPVAR32(t,z1,s,z2,7,7,0,2,3,)							\
		bf[p%16]^=t##0##z1;			bf[(p+1)%16]^=t##1##z1;		\
		bf[(p+2)%16]^=t##2##z1;		bf[(p+3)%16]^=t##3##z1;		\
		bf[(p+4)%16]^=t##4##z1;		bf[(p+5)%16]^=t##5##z1;		\
		bf[(p+6)%16]^=t##6##z1;		bf[(p+7)%16]^=t##7##z1;		\
		t##7##z1^=bf[(p+11)%16];								\
	} while (0)

/* One round for optimized LUX-384 and LUX-512.  */
#define ONEROUND64(offSet,t,z1,s,z2,bf,p,data)				\
	do {													\
		s##0##z2^=*(u64 *)(data+offSet);					\
		bf[(p+13)%16]^=*(u64 *)(data+offSet);				\
		UPVAR64(t,z1,s,z2,0,0,1,2,3,4,5,6,7,^0x2ad01c64);	\
		UPVAR64(t,z1,s,z2,1,1,2,3,4,5,6,7,0,);				\
		UPVAR64(t,z1,s,z2,2,2,3,4,5,6,7,0,1,);				\
		UPVAR64(t,z1,s,z2,3,3,4,5,6,7,0,1,2,);				\
		UPVAR64(t,z1,s,z2,4,4,5,6,7,0,1,2,3,);				\
		UPVAR64(t,z1,s,z2,5,5,6,7,0,1,2,3,4,);				\
		UPVAR64(t,z1,s,z2,6,6,7,0,1,2,3,4,5,);				\
		UPVAR64(t,z1,s,z2,7,7,0,1,2,3,4,5,6,);				\
		bf[p%16]^=t##0##z1;			bf[(p+1)%16]^=t##1##z1;	\
		bf[(p+2)%16]^=t##2##z1;		bf[(p+3)%16]^=t##3##z1;	\
		bf[(p+4)%16]^=t##4##z1;		bf[(p+5)%16]^=t##5##z1;	\
		bf[(p+6)%16]^=t##6##z1;		bf[(p+7)%16]^=t##7##z1;	\
		t##7##z1^=bf[(p+11)%16];							\
	} while (0)

/* One round of LUX-256 */
void compressSmallChunk(hashState *st, const BitSequence *data){
	int i;
	u32 temp;
	u32 t0,t1,t2,t3,t4,t5,t6,t7;

	/* Addition of the message block to the buffer and the core  */
	st->core[0]^=*(u32 *)(data+0);
	st->buffer[0]^=*( u32 *)(data+0);

    /* Core transformation G  */
	t0= Te0[(st->core[0] >> 24) & 0xff] ^ Te1[(st->core[1] >> 16) & 0xff] ^ Te2[(st->core[3] >> 8) & 0xff] ^ Te3[(st->core[4] >> 0) & 0xff]^0x2ad01c64;;
	t1= Te0[(st->core[1] >> 24) & 0xff] ^ Te1[(st->core[2] >> 16) & 0xff] ^ Te2[(st->core[4] >> 8) & 0xff] ^ Te3[(st->core[5] >> 0) & 0xff];;
	t2= Te0[(st->core[2] >> 24) & 0xff] ^ Te1[(st->core[3] >> 16) & 0xff] ^ Te2[(st->core[5] >> 8) & 0xff] ^ Te3[(st->core[6] >> 0) & 0xff];;
	t3= Te0[(st->core[3] >> 24) & 0xff] ^ Te1[(st->core[4] >> 16) & 0xff] ^ Te2[(st->core[6] >> 8) & 0xff] ^ Te3[(st->core[7] >> 0) & 0xff];;
	t4= Te0[(st->core[4] >> 24) & 0xff] ^ Te1[(st->core[5] >> 16) & 0xff] ^ Te2[(st->core[7] >> 8) & 0xff] ^ Te3[(st->core[0] >> 0) & 0xff];;
	t5= Te0[(st->core[5] >> 24) & 0xff] ^ Te1[(st->core[6] >> 16) & 0xff] ^ Te2[(st->core[0] >> 8) & 0xff] ^ Te3[(st->core[1] >> 0) & 0xff];;
	t6= Te0[(st->core[6] >> 24) & 0xff] ^ Te1[(st->core[7] >> 16) & 0xff] ^ Te2[(st->core[1] >> 8) & 0xff] ^ Te3[(st->core[2] >> 0) & 0xff];;
	t7= Te0[(st->core[7] >> 24) & 0xff] ^ Te1[(st->core[0] >> 16) & 0xff] ^ Te2[(st->core[2] >> 8) & 0xff] ^ Te3[(st->core[3] >> 0) & 0xff];;


	/* Buffer transformation F  */
	temp=st->buffer[15];
	for(i=15;i>0;i--)
		st->buffer[i]=st->buffer[i-1];
	st->buffer[0]=temp;

	/* Feedback from the core to the buffer. */
	st->buffer[4]^=t0; st->buffer[5]^=t1; st->buffer[6]^=t2; st->buffer[7]^=t3;
	st->buffer[8]^=t4; st->buffer[9]^=t5; st->buffer[10]^=t6; st->buffer[11]^=t7;

	/* Feedback from the buffer to the core	 */
	t7^=st->buffer[15];

	st->core[0]=t0; st->core[1]=t1; st->core[2]=t2; st->core[3]=t3;
	st->core[4]=t4; st->core[5]=t5; st->core[6]=t6; st->core[7]=t7;
}

/* One round of LUX-512 */
void compressSmallChunk64(hashState *st, const BitSequence *data){

	int i;
	u64 temp;
	u64 tt0,tt1,tt2,tt3,tt4,tt5,tt6,tt7;

	st->core64[0]^=*(u64 *)(data+0);
	st->buffer64[0]^=*(u64 *)(data+0);

	tt0= T640[(st->core64[0] >> 56) & 0xff] ^ T641[(st->core64[1] >> 48) & 0xff] ^ T642[(st->core64[2] >> 40) & 0xff] ^ T643[(st->core64[3] >> 32) & 0xff] ^ T644[(st->core64[4] >> 24) & 0xff] ^ T645[(st->core64[5] >> 16) & 0xff] ^ T646[(st->core64[6] >> 8) & 0xff] ^ T647[(st->core64[7] >> 0) & 0xff]^0x2ad01c64;;
	tt1= T640[(st->core64[1] >> 56) & 0xff] ^ T641[(st->core64[2] >> 48) & 0xff] ^ T642[(st->core64[3] >> 40) & 0xff] ^ T643[(st->core64[4] >> 32) & 0xff] ^ T644[(st->core64[5] >> 24) & 0xff] ^ T645[(st->core64[6] >> 16) & 0xff] ^ T646[(st->core64[7] >> 8) & 0xff] ^ T647[(st->core64[0] >> 0) & 0xff];;
	tt2= T640[(st->core64[2] >> 56) & 0xff] ^ T641[(st->core64[3] >> 48) & 0xff] ^ T642[(st->core64[4] >> 40) & 0xff] ^ T643[(st->core64[5] >> 32) & 0xff] ^ T644[(st->core64[6] >> 24) & 0xff] ^ T645[(st->core64[7] >> 16) & 0xff] ^ T646[(st->core64[0] >> 8) & 0xff] ^ T647[(st->core64[1] >> 0) & 0xff];;
	tt3= T640[(st->core64[3] >> 56) & 0xff] ^ T641[(st->core64[4] >> 48) & 0xff] ^ T642[(st->core64[5] >> 40) & 0xff] ^ T643[(st->core64[6] >> 32) & 0xff] ^ T644[(st->core64[7] >> 24) & 0xff] ^ T645[(st->core64[0] >> 16) & 0xff] ^ T646[(st->core64[1] >> 8) & 0xff] ^ T647[(st->core64[2] >> 0) & 0xff];;
	tt4= T640[(st->core64[4] >> 56) & 0xff] ^ T641[(st->core64[5] >> 48) & 0xff] ^ T642[(st->core64[6] >> 40) & 0xff] ^ T643[(st->core64[7] >> 32) & 0xff] ^ T644[(st->core64[0] >> 24) & 0xff] ^ T645[(st->core64[1] >> 16) & 0xff] ^ T646[(st->core64[2] >> 8) & 0xff] ^ T647[(st->core64[3] >> 0) & 0xff];;
	tt5= T640[(st->core64[5] >> 56) & 0xff] ^ T641[(st->core64[6] >> 48) & 0xff] ^ T642[(st->core64[7] >> 40) & 0xff] ^ T643[(st->core64[0] >> 32) & 0xff] ^ T644[(st->core64[1] >> 24) & 0xff] ^ T645[(st->core64[2] >> 16) & 0xff] ^ T646[(st->core64[3] >> 8) & 0xff] ^ T647[(st->core64[4] >> 0) & 0xff];;
	tt6= T640[(st->core64[6] >> 56) & 0xff] ^ T641[(st->core64[7] >> 48) & 0xff] ^ T642[(st->core64[0] >> 40) & 0xff] ^ T643[(st->core64[1] >> 32) & 0xff] ^ T644[(st->core64[2] >> 24) & 0xff] ^ T645[(st->core64[3] >> 16) & 0xff] ^ T646[(st->core64[4] >> 8) & 0xff] ^ T647[(st->core64[5] >> 0) & 0xff];;
	tt7= T640[(st->core64[7] >> 56) & 0xff] ^ T641[(st->core64[0] >> 48) & 0xff] ^ T642[(st->core64[1] >> 40) & 0xff] ^ T643[(st->core64[2] >> 32) & 0xff] ^ T644[(st->core64[3] >> 24) & 0xff] ^ T645[(st->core64[4] >> 16) & 0xff] ^ T646[(st->core64[5] >> 8) & 0xff] ^ T647[(st->core64[6] >> 0) & 0xff];;

	temp=st->buffer64[15];
	for(i=15;i>0;i--)
		st->buffer64[i]=st->buffer64[i-1];
	st->buffer64[0]=temp;

	st->buffer64[4]^=tt0; st->buffer64[5]^=tt1; st->buffer64[6]^=tt2; st->buffer64[7]^=tt3;
	st->buffer64[8]^=tt4; st->buffer64[9]^=tt5; st->buffer64[10]^=tt6; st->buffer64[11]^=tt7;

	tt7^=st->buffer64[15];

	st->core64[0]=tt0;st->core64[1]=tt1;st->core64[2]=tt2;st->core64[3]=tt3;
	st->core64[4]=tt4;st->core64[5]=tt5;st->core64[6]=tt6;st->core64[7]=tt7;
}

/* 16 rounds are processed. This way, the rotations of the buffer can be avoided.   */
void compressBigChunk(hashState *st, const BitSequence *data){
	unsigned long int i;
	u32 ivo[16];
	u32 s0,s1,s2,s3,s4,s5,s6,s7;
	u32 t0,t1,t2,t3,t4,t5,t6,t7;

	for(i=0;i<16;i++){
		ivo[i]=st->buffer[i];
	}

	do { st->core[0]^=*(u32 *)(data+0); ivo[(3+13)%16]^=*(u32 *)(data+0); t0= Te0[(st->core[0] >> 24) & 0xff] ^ Te1[(st->core[1] >> 16) & 0xff] ^ Te2[(st->core[3] >> 8) & 0xff] ^ Te3[(st->core[4] >> 0) & 0xff]^0x2ad01c64; t1= Te0[(st->core[1] >> 24) & 0xff] ^ Te1[(st->core[2] >> 16) & 0xff] ^ Te2[(st->core[4] >> 8) & 0xff] ^ Te3[(st->core[5] >> 0) & 0xff]; t2= Te0[(st->core[2] >> 24) & 0xff] ^ Te1[(st->core[3] >> 16) & 0xff] ^ Te2[(st->core[5] >> 8) & 0xff] ^ Te3[(st->core[6] >> 0) & 0xff]; t3= Te0[(st->core[3] >> 24) & 0xff] ^ Te1[(st->core[4] >> 16) & 0xff] ^ Te2[(st->core[6] >> 8) & 0xff] ^ Te3[(st->core[7] >> 0) & 0xff]; t4= Te0[(st->core[4] >> 24) & 0xff] ^ Te1[(st->core[5] >> 16) & 0xff] ^ Te2[(st->core[7] >> 8) & 0xff] ^ Te3[(st->core[0] >> 0) & 0xff]; t5= Te0[(st->core[5] >> 24) & 0xff] ^ Te1[(st->core[6] >> 16) & 0xff] ^ Te2[(st->core[0] >> 8) & 0xff] ^ Te3[(st->core[1] >> 0) & 0xff]; t6= Te0[(st->core[6] >> 24) & 0xff] ^ Te1[(st->core[7] >> 16) & 0xff] ^ Te2[(st->core[1] >> 8) & 0xff] ^ Te3[(st->core[2] >> 0) & 0xff]; t7= Te0[(st->core[7] >> 24) & 0xff] ^ Te1[(st->core[0] >> 16) & 0xff] ^ Te2[(st->core[2] >> 8) & 0xff] ^ Te3[(st->core[3] >> 0) & 0xff]; ivo[3%16]^=t0; ivo[(3+1)%16]^=t1; ivo[(3+2)%16]^=t2; ivo[(3+3)%16]^=t3; ivo[(3+4)%16]^=t4; ivo[(3+5)%16]^=t5; ivo[(3+6)%16]^=t6; ivo[(3+7)%16]^=t7; t7^=ivo[(3+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+4); ivo[(2+13)%16]^=*(u32 *)(data+4); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[2%16]^=s0; ivo[(2+1)%16]^=s1; ivo[(2+2)%16]^=s2; ivo[(2+3)%16]^=s3; ivo[(2+4)%16]^=s4; ivo[(2+5)%16]^=s5; ivo[(2+6)%16]^=s6; ivo[(2+7)%16]^=s7; s7^=ivo[(2+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+8); ivo[(1+13)%16]^=*(u32 *)(data+8); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[1%16]^=t0; ivo[(1+1)%16]^=t1; ivo[(1+2)%16]^=t2; ivo[(1+3)%16]^=t3; ivo[(1+4)%16]^=t4; ivo[(1+5)%16]^=t5; ivo[(1+6)%16]^=t6; ivo[(1+7)%16]^=t7; t7^=ivo[(1+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+12); ivo[(0+13)%16]^=*(u32 *)(data+12); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[0%16]^=s0; ivo[(0+1)%16]^=s1; ivo[(0+2)%16]^=s2; ivo[(0+3)%16]^=s3; ivo[(0+4)%16]^=s4; ivo[(0+5)%16]^=s5; ivo[(0+6)%16]^=s6; ivo[(0+7)%16]^=s7; s7^=ivo[(0+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+16); ivo[(15+13)%16]^=*(u32 *)(data+16); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[15%16]^=t0; ivo[(15+1)%16]^=t1; ivo[(15+2)%16]^=t2; ivo[(15+3)%16]^=t3; ivo[(15+4)%16]^=t4; ivo[(15+5)%16]^=t5; ivo[(15+6)%16]^=t6; ivo[(15+7)%16]^=t7; t7^=ivo[(15+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+20); ivo[(14+13)%16]^=*(u32 *)(data+20); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[14%16]^=s0; ivo[(14+1)%16]^=s1; ivo[(14+2)%16]^=s2; ivo[(14+3)%16]^=s3; ivo[(14+4)%16]^=s4; ivo[(14+5)%16]^=s5; ivo[(14+6)%16]^=s6; ivo[(14+7)%16]^=s7; s7^=ivo[(14+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+24); ivo[(13+13)%16]^=*(u32 *)(data+24); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[13%16]^=t0; ivo[(13+1)%16]^=t1; ivo[(13+2)%16]^=t2; ivo[(13+3)%16]^=t3; ivo[(13+4)%16]^=t4; ivo[(13+5)%16]^=t5; ivo[(13+6)%16]^=t6; ivo[(13+7)%16]^=t7; t7^=ivo[(13+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+28); ivo[(12+13)%16]^=*(u32 *)(data+28); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[12%16]^=s0; ivo[(12+1)%16]^=s1; ivo[(12+2)%16]^=s2; ivo[(12+3)%16]^=s3; ivo[(12+4)%16]^=s4; ivo[(12+5)%16]^=s5; ivo[(12+6)%16]^=s6; ivo[(12+7)%16]^=s7; s7^=ivo[(12+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+32); ivo[(11+13)%16]^=*(u32 *)(data+32); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[11%16]^=t0; ivo[(11+1)%16]^=t1; ivo[(11+2)%16]^=t2; ivo[(11+3)%16]^=t3; ivo[(11+4)%16]^=t4; ivo[(11+5)%16]^=t5; ivo[(11+6)%16]^=t6; ivo[(11+7)%16]^=t7; t7^=ivo[(11+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+36); ivo[(10+13)%16]^=*(u32 *)(data+36); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[10%16]^=s0; ivo[(10+1)%16]^=s1; ivo[(10+2)%16]^=s2; ivo[(10+3)%16]^=s3; ivo[(10+4)%16]^=s4; ivo[(10+5)%16]^=s5; ivo[(10+6)%16]^=s6; ivo[(10+7)%16]^=s7; s7^=ivo[(10+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+40); ivo[(9+13)%16]^=*(u32 *)(data+40); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[9%16]^=t0; ivo[(9+1)%16]^=t1; ivo[(9+2)%16]^=t2; ivo[(9+3)%16]^=t3; ivo[(9+4)%16]^=t4; ivo[(9+5)%16]^=t5; ivo[(9+6)%16]^=t6; ivo[(9+7)%16]^=t7; t7^=ivo[(9+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+44); ivo[(8+13)%16]^=*(u32 *)(data+44); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[8%16]^=s0; ivo[(8+1)%16]^=s1; ivo[(8+2)%16]^=s2; ivo[(8+3)%16]^=s3; ivo[(8+4)%16]^=s4; ivo[(8+5)%16]^=s5; ivo[(8+6)%16]^=s6; ivo[(8+7)%16]^=s7; s7^=ivo[(8+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+48); ivo[(7+13)%16]^=*(u32 *)(data+48); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[7%16]^=t0; ivo[(7+1)%16]^=t1; ivo[(7+2)%16]^=t2; ivo[(7+3)%16]^=t3; ivo[(7+4)%16]^=t4; ivo[(7+5)%16]^=t5; ivo[(7+6)%16]^=t6; ivo[(7+7)%16]^=t7; t7^=ivo[(7+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+52); ivo[(6+13)%16]^=*(u32 *)(data+52); s0= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; s1= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; s2= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; s3= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; s4= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; s5= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; s6= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; s7= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[6%16]^=s0; ivo[(6+1)%16]^=s1; ivo[(6+2)%16]^=s2; ivo[(6+3)%16]^=s3; ivo[(6+4)%16]^=s4; ivo[(6+5)%16]^=s5; ivo[(6+6)%16]^=s6; ivo[(6+7)%16]^=s7; s7^=ivo[(6+11)%16]; } while (0);
	do { s0^=*(u32 *)(data+56); ivo[(5+13)%16]^=*(u32 *)(data+56); t0= Te0[(s0 >> 24) & 0xff] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[(s4 >> 0) & 0xff]^0x2ad01c64; t1= Te0[(s1 >> 24) & 0xff] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s4 >> 8) & 0xff] ^ Te3[(s5 >> 0) & 0xff]; t2= Te0[(s2 >> 24) & 0xff] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s5 >> 8) & 0xff] ^ Te3[(s6 >> 0) & 0xff]; t3= Te0[(s3 >> 24) & 0xff] ^ Te1[(s4 >> 16) & 0xff] ^ Te2[(s6 >> 8) & 0xff] ^ Te3[(s7 >> 0) & 0xff]; t4= Te0[(s4 >> 24) & 0xff] ^ Te1[(s5 >> 16) & 0xff] ^ Te2[(s7 >> 8) & 0xff] ^ Te3[(s0 >> 0) & 0xff]; t5= Te0[(s5 >> 24) & 0xff] ^ Te1[(s6 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[(s1 >> 0) & 0xff]; t6= Te0[(s6 >> 24) & 0xff] ^ Te1[(s7 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[(s2 >> 0) & 0xff]; t7= Te0[(s7 >> 24) & 0xff] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[(s3 >> 0) & 0xff]; ivo[5%16]^=t0; ivo[(5+1)%16]^=t1; ivo[(5+2)%16]^=t2; ivo[(5+3)%16]^=t3; ivo[(5+4)%16]^=t4; ivo[(5+5)%16]^=t5; ivo[(5+6)%16]^=t6; ivo[(5+7)%16]^=t7; t7^=ivo[(5+11)%16]; } while (0);
	do { t0^=*(u32 *)(data+60); ivo[(4+13)%16]^=*(u32 *)(data+60); st->core[0]= Te0[(t0 >> 24) & 0xff] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[(t4 >> 0) & 0xff]^0x2ad01c64; st->core[1]= Te0[(t1 >> 24) & 0xff] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t4 >> 8) & 0xff] ^ Te3[(t5 >> 0) & 0xff]; st->core[2]= Te0[(t2 >> 24) & 0xff] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t5 >> 8) & 0xff] ^ Te3[(t6 >> 0) & 0xff]; st->core[3]= Te0[(t3 >> 24) & 0xff] ^ Te1[(t4 >> 16) & 0xff] ^ Te2[(t6 >> 8) & 0xff] ^ Te3[(t7 >> 0) & 0xff]; st->core[4]= Te0[(t4 >> 24) & 0xff] ^ Te1[(t5 >> 16) & 0xff] ^ Te2[(t7 >> 8) & 0xff] ^ Te3[(t0 >> 0) & 0xff]; st->core[5]= Te0[(t5 >> 24) & 0xff] ^ Te1[(t6 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[(t1 >> 0) & 0xff]; st->core[6]= Te0[(t6 >> 24) & 0xff] ^ Te1[(t7 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[(t2 >> 0) & 0xff]; st->core[7]= Te0[(t7 >> 24) & 0xff] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[(t3 >> 0) & 0xff]; ivo[4%16]^=st->core[0]; ivo[(4+1)%16]^=st->core[1]; ivo[(4+2)%16]^=st->core[2]; ivo[(4+3)%16]^=st->core[3]; ivo[(4+4)%16]^=st->core[4]; ivo[(4+5)%16]^=st->core[5]; ivo[(4+6)%16]^=st->core[6]; ivo[(4+7)%16]^=st->core[7]; st->core[7]^=ivo[(4+11)%16]; } while (0);


	for(i=0;i<16;i++){
		st->buffer[i]=ivo[i];
	}
}

/*	16 rounds for LUX-384 and LUX-512 are processed.
	This way, the rotations of the buffer can be avoided.
 */
void compressBigChunk64(hashState *st, const BitSequence *data){
	unsigned long int i;
	u64 ivo[16];
	u64 s0,s1,s2,s3,s4,s5,s6,s7;
	u64 t0,t1,t2,t3,t4,t5,t6,t7;

	for(i=0;i<16;i++){
		ivo[i]=st->buffer64[i];
	}

	do { st->core64[0]^=*(u64 *)(data+0); ivo[(3+13)%16]^=*(u64 *)(data+0); t0= T640[(st->core64[0] >> 56) & 0xff] ^ T641[(st->core64[1] >> 48) & 0xff] ^ T642[(st->core64[2] >> 40) & 0xff] ^ T643[(st->core64[3] >> 32) & 0xff] ^ T644[(st->core64[4] >> 24) & 0xff] ^ T645[(st->core64[5] >> 16) & 0xff] ^ T646[(st->core64[6] >> 8) & 0xff] ^ T647[(st->core64[7] >> 0) & 0xff]^0x2ad01c64;; t1= T640[(st->core64[1] >> 56) & 0xff] ^ T641[(st->core64[2] >> 48) & 0xff] ^ T642[(st->core64[3] >> 40) & 0xff] ^ T643[(st->core64[4] >> 32) & 0xff] ^ T644[(st->core64[5] >> 24) & 0xff] ^ T645[(st->core64[6] >> 16) & 0xff] ^ T646[(st->core64[7] >> 8) & 0xff] ^ T647[(st->core64[0] >> 0) & 0xff];; t2= T640[(st->core64[2] >> 56) & 0xff] ^ T641[(st->core64[3] >> 48) & 0xff] ^ T642[(st->core64[4] >> 40) & 0xff] ^ T643[(st->core64[5] >> 32) & 0xff] ^ T644[(st->core64[6] >> 24) & 0xff] ^ T645[(st->core64[7] >> 16) & 0xff] ^ T646[(st->core64[0] >> 8) & 0xff] ^ T647[(st->core64[1] >> 0) & 0xff];; t3= T640[(st->core64[3] >> 56) & 0xff] ^ T641[(st->core64[4] >> 48) & 0xff] ^ T642[(st->core64[5] >> 40) & 0xff] ^ T643[(st->core64[6] >> 32) & 0xff] ^ T644[(st->core64[7] >> 24) & 0xff] ^ T645[(st->core64[0] >> 16) & 0xff] ^ T646[(st->core64[1] >> 8) & 0xff] ^ T647[(st->core64[2] >> 0) & 0xff];; t4= T640[(st->core64[4] >> 56) & 0xff] ^ T641[(st->core64[5] >> 48) & 0xff] ^ T642[(st->core64[6] >> 40) & 0xff] ^ T643[(st->core64[7] >> 32) & 0xff] ^ T644[(st->core64[0] >> 24) & 0xff] ^ T645[(st->core64[1] >> 16) & 0xff] ^ T646[(st->core64[2] >> 8) & 0xff] ^ T647[(st->core64[3] >> 0) & 0xff];; t5= T640[(st->core64[5] >> 56) & 0xff] ^ T641[(st->core64[6] >> 48) & 0xff] ^ T642[(st->core64[7] >> 40) & 0xff] ^ T643[(st->core64[0] >> 32) & 0xff] ^ T644[(st->core64[1] >> 24) & 0xff] ^ T645[(st->core64[2] >> 16) & 0xff] ^ T646[(st->core64[3] >> 8) & 0xff] ^ T647[(st->core64[4] >> 0) & 0xff];; t6= T640[(st->core64[6] >> 56) & 0xff] ^ T641[(st->core64[7] >> 48) & 0xff] ^ T642[(st->core64[0] >> 40) & 0xff] ^ T643[(st->core64[1] >> 32) & 0xff] ^ T644[(st->core64[2] >> 24) & 0xff] ^ T645[(st->core64[3] >> 16) & 0xff] ^ T646[(st->core64[4] >> 8) & 0xff] ^ T647[(st->core64[5] >> 0) & 0xff];; t7= T640[(st->core64[7] >> 56) & 0xff] ^ T641[(st->core64[0] >> 48) & 0xff] ^ T642[(st->core64[1] >> 40) & 0xff] ^ T643[(st->core64[2] >> 32) & 0xff] ^ T644[(st->core64[3] >> 24) & 0xff] ^ T645[(st->core64[4] >> 16) & 0xff] ^ T646[(st->core64[5] >> 8) & 0xff] ^ T647[(st->core64[6] >> 0) & 0xff];; ivo[3%16]^=t0; ivo[(3+1)%16]^=t1; ivo[(3+2)%16]^=t2; ivo[(3+3)%16]^=t3; ivo[(3+4)%16]^=t4; ivo[(3+5)%16]^=t5; ivo[(3+6)%16]^=t6; ivo[(3+7)%16]^=t7; t7^=ivo[(3+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+8); ivo[(2+13)%16]^=*(u64 *)(data+8); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[2%16]^=s0; ivo[(2+1)%16]^=s1; ivo[(2+2)%16]^=s2; ivo[(2+3)%16]^=s3; ivo[(2+4)%16]^=s4; ivo[(2+5)%16]^=s5; ivo[(2+6)%16]^=s6; ivo[(2+7)%16]^=s7; s7^=ivo[(2+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+16); ivo[(1+13)%16]^=*(u64 *)(data+16); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[1%16]^=t0; ivo[(1+1)%16]^=t1; ivo[(1+2)%16]^=t2; ivo[(1+3)%16]^=t3; ivo[(1+4)%16]^=t4; ivo[(1+5)%16]^=t5; ivo[(1+6)%16]^=t6; ivo[(1+7)%16]^=t7; t7^=ivo[(1+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+24); ivo[(0+13)%16]^=*(u64 *)(data+24); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[0%16]^=s0; ivo[(0+1)%16]^=s1; ivo[(0+2)%16]^=s2; ivo[(0+3)%16]^=s3; ivo[(0+4)%16]^=s4; ivo[(0+5)%16]^=s5; ivo[(0+6)%16]^=s6; ivo[(0+7)%16]^=s7; s7^=ivo[(0+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+32); ivo[(15+13)%16]^=*(u64 *)(data+32); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[15%16]^=t0; ivo[(15+1)%16]^=t1; ivo[(15+2)%16]^=t2; ivo[(15+3)%16]^=t3; ivo[(15+4)%16]^=t4; ivo[(15+5)%16]^=t5; ivo[(15+6)%16]^=t6; ivo[(15+7)%16]^=t7; t7^=ivo[(15+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+40); ivo[(14+13)%16]^=*(u64 *)(data+40); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[14%16]^=s0; ivo[(14+1)%16]^=s1; ivo[(14+2)%16]^=s2; ivo[(14+3)%16]^=s3; ivo[(14+4)%16]^=s4; ivo[(14+5)%16]^=s5; ivo[(14+6)%16]^=s6; ivo[(14+7)%16]^=s7; s7^=ivo[(14+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+48); ivo[(13+13)%16]^=*(u64 *)(data+48); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[13%16]^=t0; ivo[(13+1)%16]^=t1; ivo[(13+2)%16]^=t2; ivo[(13+3)%16]^=t3; ivo[(13+4)%16]^=t4; ivo[(13+5)%16]^=t5; ivo[(13+6)%16]^=t6; ivo[(13+7)%16]^=t7; t7^=ivo[(13+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+56); ivo[(12+13)%16]^=*(u64 *)(data+56); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[12%16]^=s0; ivo[(12+1)%16]^=s1; ivo[(12+2)%16]^=s2; ivo[(12+3)%16]^=s3; ivo[(12+4)%16]^=s4; ivo[(12+5)%16]^=s5; ivo[(12+6)%16]^=s6; ivo[(12+7)%16]^=s7; s7^=ivo[(12+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+64); ivo[(11+13)%16]^=*(u64 *)(data+64); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[11%16]^=t0; ivo[(11+1)%16]^=t1; ivo[(11+2)%16]^=t2; ivo[(11+3)%16]^=t3; ivo[(11+4)%16]^=t4; ivo[(11+5)%16]^=t5; ivo[(11+6)%16]^=t6; ivo[(11+7)%16]^=t7; t7^=ivo[(11+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+72); ivo[(10+13)%16]^=*(u64 *)(data+72); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[10%16]^=s0; ivo[(10+1)%16]^=s1; ivo[(10+2)%16]^=s2; ivo[(10+3)%16]^=s3; ivo[(10+4)%16]^=s4; ivo[(10+5)%16]^=s5; ivo[(10+6)%16]^=s6; ivo[(10+7)%16]^=s7; s7^=ivo[(10+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+80); ivo[(9+13)%16]^=*(u64 *)(data+80); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[9%16]^=t0; ivo[(9+1)%16]^=t1; ivo[(9+2)%16]^=t2; ivo[(9+3)%16]^=t3; ivo[(9+4)%16]^=t4; ivo[(9+5)%16]^=t5; ivo[(9+6)%16]^=t6; ivo[(9+7)%16]^=t7; t7^=ivo[(9+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+88); ivo[(8+13)%16]^=*(u64 *)(data+88); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[8%16]^=s0; ivo[(8+1)%16]^=s1; ivo[(8+2)%16]^=s2; ivo[(8+3)%16]^=s3; ivo[(8+4)%16]^=s4; ivo[(8+5)%16]^=s5; ivo[(8+6)%16]^=s6; ivo[(8+7)%16]^=s7; s7^=ivo[(8+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+96); ivo[(7+13)%16]^=*(u64 *)(data+96); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[7%16]^=t0; ivo[(7+1)%16]^=t1; ivo[(7+2)%16]^=t2; ivo[(7+3)%16]^=t3; ivo[(7+4)%16]^=t4; ivo[(7+5)%16]^=t5; ivo[(7+6)%16]^=t6; ivo[(7+7)%16]^=t7; t7^=ivo[(7+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+104); ivo[(6+13)%16]^=*(u64 *)(data+104); s0= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; s1= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; s2= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; s3= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; s4= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; s5= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; s6= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; s7= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[6%16]^=s0; ivo[(6+1)%16]^=s1; ivo[(6+2)%16]^=s2; ivo[(6+3)%16]^=s3; ivo[(6+4)%16]^=s4; ivo[(6+5)%16]^=s5; ivo[(6+6)%16]^=s6; ivo[(6+7)%16]^=s7; s7^=ivo[(6+11)%16]; } while (0);
	do { s0^=*(u64 *)(data+112); ivo[(5+13)%16]^=*(u64 *)(data+112); t0= T640[(s0 >> 56) & 0xff] ^ T641[(s1 >> 48) & 0xff] ^ T642[(s2 >> 40) & 0xff] ^ T643[(s3 >> 32) & 0xff] ^ T644[(s4 >> 24) & 0xff] ^ T645[(s5 >> 16) & 0xff] ^ T646[(s6 >> 8) & 0xff] ^ T647[(s7 >> 0) & 0xff]^0x2ad01c64;; t1= T640[(s1 >> 56) & 0xff] ^ T641[(s2 >> 48) & 0xff] ^ T642[(s3 >> 40) & 0xff] ^ T643[(s4 >> 32) & 0xff] ^ T644[(s5 >> 24) & 0xff] ^ T645[(s6 >> 16) & 0xff] ^ T646[(s7 >> 8) & 0xff] ^ T647[(s0 >> 0) & 0xff];; t2= T640[(s2 >> 56) & 0xff] ^ T641[(s3 >> 48) & 0xff] ^ T642[(s4 >> 40) & 0xff] ^ T643[(s5 >> 32) & 0xff] ^ T644[(s6 >> 24) & 0xff] ^ T645[(s7 >> 16) & 0xff] ^ T646[(s0 >> 8) & 0xff] ^ T647[(s1 >> 0) & 0xff];; t3= T640[(s3 >> 56) & 0xff] ^ T641[(s4 >> 48) & 0xff] ^ T642[(s5 >> 40) & 0xff] ^ T643[(s6 >> 32) & 0xff] ^ T644[(s7 >> 24) & 0xff] ^ T645[(s0 >> 16) & 0xff] ^ T646[(s1 >> 8) & 0xff] ^ T647[(s2 >> 0) & 0xff];; t4= T640[(s4 >> 56) & 0xff] ^ T641[(s5 >> 48) & 0xff] ^ T642[(s6 >> 40) & 0xff] ^ T643[(s7 >> 32) & 0xff] ^ T644[(s0 >> 24) & 0xff] ^ T645[(s1 >> 16) & 0xff] ^ T646[(s2 >> 8) & 0xff] ^ T647[(s3 >> 0) & 0xff];; t5= T640[(s5 >> 56) & 0xff] ^ T641[(s6 >> 48) & 0xff] ^ T642[(s7 >> 40) & 0xff] ^ T643[(s0 >> 32) & 0xff] ^ T644[(s1 >> 24) & 0xff] ^ T645[(s2 >> 16) & 0xff] ^ T646[(s3 >> 8) & 0xff] ^ T647[(s4 >> 0) & 0xff];; t6= T640[(s6 >> 56) & 0xff] ^ T641[(s7 >> 48) & 0xff] ^ T642[(s0 >> 40) & 0xff] ^ T643[(s1 >> 32) & 0xff] ^ T644[(s2 >> 24) & 0xff] ^ T645[(s3 >> 16) & 0xff] ^ T646[(s4 >> 8) & 0xff] ^ T647[(s5 >> 0) & 0xff];; t7= T640[(s7 >> 56) & 0xff] ^ T641[(s0 >> 48) & 0xff] ^ T642[(s1 >> 40) & 0xff] ^ T643[(s2 >> 32) & 0xff] ^ T644[(s3 >> 24) & 0xff] ^ T645[(s4 >> 16) & 0xff] ^ T646[(s5 >> 8) & 0xff] ^ T647[(s6 >> 0) & 0xff];; ivo[5%16]^=t0; ivo[(5+1)%16]^=t1; ivo[(5+2)%16]^=t2; ivo[(5+3)%16]^=t3; ivo[(5+4)%16]^=t4; ivo[(5+5)%16]^=t5; ivo[(5+6)%16]^=t6; ivo[(5+7)%16]^=t7; t7^=ivo[(5+11)%16]; } while (0);
	do { t0^=*(u64 *)(data+120); ivo[(4+13)%16]^=*(u64 *)(data+120); st->core64[0]= T640[(t0 >> 56) & 0xff] ^ T641[(t1 >> 48) & 0xff] ^ T642[(t2 >> 40) & 0xff] ^ T643[(t3 >> 32) & 0xff] ^ T644[(t4 >> 24) & 0xff] ^ T645[(t5 >> 16) & 0xff] ^ T646[(t6 >> 8) & 0xff] ^ T647[(t7 >> 0) & 0xff]^0x2ad01c64;; st->core64[1]= T640[(t1 >> 56) & 0xff] ^ T641[(t2 >> 48) & 0xff] ^ T642[(t3 >> 40) & 0xff] ^ T643[(t4 >> 32) & 0xff] ^ T644[(t5 >> 24) & 0xff] ^ T645[(t6 >> 16) & 0xff] ^ T646[(t7 >> 8) & 0xff] ^ T647[(t0 >> 0) & 0xff];; st->core64[2]= T640[(t2 >> 56) & 0xff] ^ T641[(t3 >> 48) & 0xff] ^ T642[(t4 >> 40) & 0xff] ^ T643[(t5 >> 32) & 0xff] ^ T644[(t6 >> 24) & 0xff] ^ T645[(t7 >> 16) & 0xff] ^ T646[(t0 >> 8) & 0xff] ^ T647[(t1 >> 0) & 0xff];; st->core64[3]= T640[(t3 >> 56) & 0xff] ^ T641[(t4 >> 48) & 0xff] ^ T642[(t5 >> 40) & 0xff] ^ T643[(t6 >> 32) & 0xff] ^ T644[(t7 >> 24) & 0xff] ^ T645[(t0 >> 16) & 0xff] ^ T646[(t1 >> 8) & 0xff] ^ T647[(t2 >> 0) & 0xff];; st->core64[4]= T640[(t4 >> 56) & 0xff] ^ T641[(t5 >> 48) & 0xff] ^ T642[(t6 >> 40) & 0xff] ^ T643[(t7 >> 32) & 0xff] ^ T644[(t0 >> 24) & 0xff] ^ T645[(t1 >> 16) & 0xff] ^ T646[(t2 >> 8) & 0xff] ^ T647[(t3 >> 0) & 0xff];; st->core64[5]= T640[(t5 >> 56) & 0xff] ^ T641[(t6 >> 48) & 0xff] ^ T642[(t7 >> 40) & 0xff] ^ T643[(t0 >> 32) & 0xff] ^ T644[(t1 >> 24) & 0xff] ^ T645[(t2 >> 16) & 0xff] ^ T646[(t3 >> 8) & 0xff] ^ T647[(t4 >> 0) & 0xff];; st->core64[6]= T640[(t6 >> 56) & 0xff] ^ T641[(t7 >> 48) & 0xff] ^ T642[(t0 >> 40) & 0xff] ^ T643[(t1 >> 32) & 0xff] ^ T644[(t2 >> 24) & 0xff] ^ T645[(t3 >> 16) & 0xff] ^ T646[(t4 >> 8) & 0xff] ^ T647[(t5 >> 0) & 0xff];; st->core64[7]= T640[(t7 >> 56) & 0xff] ^ T641[(t0 >> 48) & 0xff] ^ T642[(t1 >> 40) & 0xff] ^ T643[(t2 >> 32) & 0xff] ^ T644[(t3 >> 24) & 0xff] ^ T645[(t4 >> 16) & 0xff] ^ T646[(t5 >> 8) & 0xff] ^ T647[(t6 >> 0) & 0xff];; ivo[4%16]^=st->core64[0]; ivo[(4+1)%16]^=st->core64[1]; ivo[(4+2)%16]^=st->core64[2]; ivo[(4+3)%16]^=st->core64[3]; ivo[(4+4)%16]^=st->core64[4]; ivo[(4+5)%16]^=st->core64[5]; ivo[(4+6)%16]^=st->core64[6]; ivo[(4+7)%16]^=st->core64[7]; st->core64[7]^=ivo[(4+11)%16]; } while (0);

	for(i=0;i<16;i++){
		st->buffer64[i]=ivo[i];
	}
}

HashReturn Init(hashState *state, int hashbitlen){
	int i;

	state->hashbitlen=hashbitlen;
	if(!((hashbitlen==224)||(hashbitlen==256)||(hashbitlen==384)||(hashbitlen==512)))
		return BAD_HASHBITLEN;

	for(i=0;i<8;i++){
		state->core[i]=0;
		state->core64[i]=0;
	}
	for(i=0;i<16;i++){
		state->buffer[i]=0;
		state->buffer64[i]=0;
	}
	for(i=0;i<8;i++)
		state->remSeq[i]=0;

	return SUCCESS;
}

HashReturn Update(hashState *state, const BitSequence *data, DataLength databitlen){

	int i;
	unsigned long long doneLength=0;

	state->databitlen=databitlen;
	if(state->hashbitlen<=256){
		/*	First compress the big chunks of 64 bytes each
			in 16 rounds. This way the rotations of the
			buffer are costless.
		 */
		while(doneLength+64<=databitlen/8){
			compressBigChunk(state,data+doneLength);
			doneLength+=64;
		}

		/*	The rest of the input is compressed.  */
		while(doneLength+4<=databitlen/8){
			compressSmallChunk(state,data+doneLength);
			doneLength+=4;
		}
	}
	else{
		/*	First compress the big chunks of 128 bytes each
			in 16 rounds. This way the rotations of the
			buffer are costless.
		 */

		while(doneLength+128<=databitlen/8){
			compressBigChunk64(state,data+doneLength);
			doneLength+=128;
		}

		/* The rest of the input is compressed.  */
		while(doneLength+8<=databitlen/8){
			compressSmallChunk64(state,data+doneLength);
			doneLength+=8;
		}

	}

	/* The remaining input is stored for further processing in Final().	 */
	state->lenRemSeq=databitlen-8*doneLength;
	for(i=0;i<state->lenRemSeq/8+(state->lenRemSeq%8>0);i++){
			state->remSeq[i]=data[doneLength+i];
	}

	return SUCCESS;
}

HashReturn Final(hashState *state, BitSequence *hashval){
	int i;
	BitSequence empty[128];

	/*	If the block is not full then add 1 and a number of 0s.	*/
	if(state->lenRemSeq>0){
		state->remSeq[state->lenRemSeq>>3] &=(0xff)<<(8-(state->lenRemSeq & 7));
		state->remSeq[state->lenRemSeq>>3] ^=(0x01)<<(7-((state->lenRemSeq) & 7));
	}
	/*	Else create new block with 1 and 31 zeros. */
	else{
		state->remSeq[0]=0x80;
	}

	/* Hash the padded block. */
	if(state->hashbitlen<=256){
		compressSmallChunk(state,state->remSeq);
	}
	else{
		compressSmallChunk64(state,state->remSeq);
	}

	/*	Additional block(s) that contain the input
		length is(are) created and compressed. For LUX-224 and LUX-256,
		the message blocks are only 32 bits, therefore the message length
		represantion takes two block.
	*/
	for(i=0;i<8;i++)
		empty[i]   = ( (state->databitlen)>>(56-8*i) ) & 0xff;
	if(state->hashbitlen<=256){
		compressSmallChunk(state,empty);
		compressSmallChunk(state,empty+4);
	}
	else{
		compressSmallChunk64(state,empty);
	}

	/*	16 blank rounds are iterated.
		The input for the blank rounds are blocks with 0s.
		Output is value of the core element C_3.
	 */
	memset(empty, 0, 128);
	if(state->hashbitlen<=256){
		for(i=0;i<16;i++){
			compressSmallChunk(state,empty);
		}
		for(i=0;i<state->hashbitlen/32;i++){
			compressSmallChunk(state,empty);
				*(u32 *)(hashval + 4*i)=*(u32 *)(state->core + 3);
		}
	}
	else{
		for(i=0;i<16;i++){
			compressSmallChunk64(state,empty);
		}
		for(i=0;i<state->hashbitlen/64;i++){
			compressSmallChunk64(state,empty);
			*(u64 *)(hashval + 8*i)=*(u64 *)(state->core64 + 3);
		}
	}

	return SUCCESS;
}

HashReturn Hash(int hashbitlen, const BitSequence *data, DataLength databitlen, BitSequence *hashval){
	hashState Temp;

	if(Init(&Temp,hashbitlen)==SUCCESS){
		Update(&Temp,data,databitlen );
		Final(&Temp,hashval);
		return  SUCCESS;
	}
	else return FAIL;
}

